//
//  SIRefreshControl.swift
//  SinaImiate
//
//  Created by xiaoming on 16/7/8.
//  Copyright © 2016年 GoodJob. All rights reserved.
//

import UIKit

///刷新状态切换的临界点
private let SIRefreshOffset: CGFloat = 126

///刷新状态
enum SIRefreshState {
    case Normal 
    case Pulling
    case WillRefresh
}

/// 负责处理根刷新相关的
class SIRefreshControl: UIControl {
    ///刷新控件的父视图, 下拉刷新控件应该适用于 UITableView / UICollectionView
    private weak var scrollView: UIScrollView?
    
    private lazy var refreshView: SIRefreshView = SIRefreshView.refreshView()
    
    ///构造函数
    init() {
        
        super.init(frame: CGRect())
        
        setupUI()
        
    }
    
    required init?(coder aDecoder: NSCoder) {
        
        super.init(coder: aDecoder)
        
        setupUI()
    }
    
    ///will move  addSubView方法会调用
    /// 当添加到父视图时,newSuperView是父视图  当父视图被移除为nil
    override func willMove(toSuperview newSuperview: UIView?) {
        
        guard let sv = newSuperview as? UIScrollView else {
            
            return
        }
        
        scrollView = sv
        
        ///KVO  键值观察模式 监听属性的变化, 通常只监听某一个对象的某几个属性, 如果属性太多,方法会很乱
        scrollView?.addObserver(self, forKeyPath: "contentOffset", options: [], context: nil)
        
    }
    
    ///所有KVO方法会统一调用此方法
    override func observeValue(forKeyPath keyPath: String?, of object: AnyObject?, change: [NSKeyValueChangeKey : AnyObject]?, context: UnsafeMutablePointer<Void>?) {
        
        guard let sv = scrollView else {
            
            return
        }
        
        let height = -(sv.contentInset.top + sv.contentOffset.y)
        
        if height < 0 {
            
            return
        }
        
        self.frame = CGRect(x: 0, y: -height, width: sv.bounds.width, height: height)
        
        print(height)
        
        if refreshView.refreshState != .WillRefresh {
            
            refreshView.parentViewHeight = height
        }
        
        
        ///判断临界点 - 只需要判断一次
        
        if sv.isDragging {
            ///高度大于临界点 并且 刷新视图的状态是Normal 这种情况可以刷新
            if height > SIRefreshOffset && (refreshView.refreshState == .Normal) {
                
                print("放手刷新")
                
                refreshView.refreshState = .Pulling
            } else if height <= SIRefreshOffset && (refreshView.refreshState == .Pulling) {
                refreshView.refreshState = .Normal
                print("在使劲...")
            }
        } else {
            
            //放手
            if refreshView.refreshState == .Pulling {
                
                print("准备开始刷新")
                ///准备开始刷新
//                refreshView.refreshState = .WillRefresh
                
                ///开始刷新
                beginRefreshing()
                
                ///发送事件
                sendActions(for: .valueChanged)
            }
        }
        
    }
    
    ///本视图从父视图上移除 所有的下拉刷新框架都是监听父视图的contentOffset 
    ///所有的框架的 KVO 监听实现思路都是这个 
    ///观察者模式, 在不需要的时候, 都需要释放
    // 通知中心如果不释放 什么也不会发生,但是会有内存泄漏,会有多注册的可能
    // KVO: 如果不释放, 会崩溃
    override func removeFromSuperview() {
        superview?.removeObserver(self, forKeyPath: "contentOffset")
        
        super.removeFromSuperview()
        
    }
    
    ///开始刷新
    func beginRefreshing() {
        print("开始刷新")
        
        guard let sv = scrollView else {
            return
        }
        
        if refreshView.refreshState == .WillRefresh {
            
            return
        }
        
        refreshView.refreshState = .WillRefresh
        
        var inset = sv.contentInset
        
        inset.top += SIRefreshOffset
        
        sv.contentInset = inset
//        sv.contentOffset.y = -inset.top
        
        refreshView.parentViewHeight = SIRefreshOffset
        
    }
    ///结束刷新
    func endRefreshing() {
        guard let sv = scrollView else {
            
            return
        }
        
        if refreshView.refreshState != .WillRefresh {
            
            return
        }
        
        refreshView.refreshState = .Normal
        
        var inset = sv.contentInset
        inset.top -= SIRefreshOffset
        
        sv.contentInset = inset
        
    
    }

}

extension SIRefreshControl {
    
    ///搭建界面
    private func setupUI() {
        
        backgroundColor = superview?.backgroundColor
        
        addSubview(refreshView)
        
        //关闭自动布局 
        refreshView.translatesAutoresizingMaskIntoConstraints = false
        
        addConstraint(NSLayoutConstraint(item: refreshView,
                                         attribute: .centerX,
                                         relatedBy: .equal,
                                         toItem: self,
                                         attribute: .centerX,
                                         multiplier: 1.0,
                                         constant: 0))
        
        addConstraint(NSLayoutConstraint(item: refreshView,
                                         attribute: .bottom,
                                         relatedBy: .equal,
                                         toItem: self,
                                         attribute: .bottom,
                                         multiplier: 1.0,
                                         constant: 0))
        
        addConstraint(NSLayoutConstraint(item: refreshView,
                                         attribute: .width,
                                         relatedBy: .equal,
                                         toItem: nil,
                                         attribute: .notAnAttribute,
                                         multiplier: 1.0,
                                         constant: refreshView.bounds.width))
        
        addConstraint(NSLayoutConstraint(item: refreshView,
                                         attribute: .height,
                                         relatedBy: .equal,
                                         toItem: nil,
                                         attribute: .notAnAttribute,
                                         multiplier: 1.0,
                                         constant: refreshView.bounds.height))
        
    }
    
}
